using System.IO;
using System.Net;

namespace RealDolmen.Helpers
{
    public class StreamHelper
    {
        #region Acces Methods
        public static Stream PrepareForReuse(string stringToStream)
        {
            Stream stream = new MemoryStream();
            StreamWriter sw = new StreamWriter(stream);
            sw.Write(stringToStream);
            sw.Flush();

            return PrepareForReuse(stream);
        }

        public static Stream PrepareForReuse(Stream stream)
        {
            stream.Position = 0;
            return stream;
        }

        public static string PeekStream(Stream stream)
        {
            PrepareForReuse(stream);

            StreamReader r = new StreamReader(stream);
            string temp = r.ReadToEnd();

            PrepareForReuse(stream);

            return temp;
        }

        public static void ReadWriteStream(Stream readStream, Stream writeStream)
        {
            int length = 512;
            byte[] buffer = new byte[length];
            int bytesRead = readStream.Read(buffer, 0, length);
            while (bytesRead > 0)
            {
                writeStream.Write(buffer, 0, bytesRead);
                bytesRead = readStream.Read(buffer, 0, length);
            }
            writeStream.Position = 0;
        } 
        #endregion // Access Methods
        
        #region Fetch Methods
		public static Stream GetStream(string path)
        {
            Stream stream = null;

            if (path.Contains("://"))
                stream = GetHttpStream(path);
            else if (path.Contains(":"))
                stream = new FileStream(path, FileMode.Open, FileAccess.Read);

            return stream;
        }

        public static Stream GetHttpStream(string url)
        {
            WebRequest request = WebRequest.Create(url);
            
            WebResponse response = GetHttpResponse(request, url);

            if (response != null)
                return response.GetResponseStream();
            else
                return null;
        }

        private static WebResponse GetHttpResponse(WebRequest request, string url)
        {
            try
            {
                return request.GetResponse();
            }
            catch (WebException ex)
            {
                HttpWebResponse httpResponse = ex.Response as HttpWebResponse;

                if(httpResponse != null)
                {
                    if (httpResponse.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        request = WebRequest.Create(url);
                        request.Credentials = CredentialCache.DefaultCredentials;
                        return GetHttpResponse(request, url);
                    }
                    if (httpResponse.StatusCode == HttpStatusCode.ProxyAuthenticationRequired)
                    {
                        request = WebRequest.Create(url);
                        request.Proxy.Credentials = CredentialCache.DefaultCredentials;
                        return GetHttpResponse(request, url);
                    }
                }
                throw ex;
            }
        }
	    #endregion // Fetch Methods
    }
}
